<?php
/**
 * ===============================================
 * 版权所有 2019-2050 青岛铁锤科技有限公司，并保留所有权利。
 * 网站地址: http://www.huaxianling.com
 * ===============================================
 * Author: Wyp
 */

namespace App\Modules\Live\Services;


use App\Exceptions\AllValidatorException;
use App\Lib\Utilities;
use App\Modules\Live\Criterias\LiveCriteria;
use App\Modules\Live\Criterias\LiveListCriteria;
use App\Modules\Live\Criterias\LiveMemberCriteria;
use App\Modules\Live\Repositories\LiveAttentionRepository;
use App\Modules\Live\Repositories\LiveLikeRepository;
use App\Modules\Live\Repositories\LiveRepository;
use App\Modules\Live\Repositories\MemberRepository;
use Flower\Core\Repository\Eloquent\BaseService;
use App\Modules\Live\Repositories\LiveMemberRepository;
use App\Lib\Facades\FLAuth;
use Illuminate\Support\Facades\DB;

class WxLiveService extends BaseService
{

    private $liveRepository;
    private $memberRepository;
    private $liveLikeRepository;
    private $liveAttentionRepository;
    private $liveMemberRepository;


    public function __construct(LiveRepository $liveRepository,
                                LiveLikeRepository $liveLikeRepository,
                                MemberRepository $memberRepository,
                                LiveAttentionRepository $liveAttentionRepository,
                                LiveMemberRepository $liveMemberRepository
    )
    {
        $this->liveRepository = $liveRepository;
        $this->memberRepository = $memberRepository;
        $this->liveLikeRepository = $liveLikeRepository;
        $this->liveMemberRepository = $liveMemberRepository;
        $this->liveAttentionRepository = $liveAttentionRepository;

    }

    /**
     * 获取直播列表
     * @param $lon
     * @param $lat
     * @param $pageSize
     * @return array
     * @throws \Flower\Core\Repository\Exceptions\RepositoryException
     */
    public function getLiveList($lon,$lat,$distance,$pageSize,$page)
    {
        if(!$lon) {
            $lon = 0;
        }
        if(!$lat) {
            $lat = 0;
        }
        $select = [
            'hx_live.id',
            'hx_live.name',
            'hx_user.id as user_id',
            'hx_user.nick as nick',
            'hx_user.portrait as portrait',
            'hx_live.member_num',
            'hx_live.picture',
            'hx_picture.image',
            'hx_store.name as store',
            'hx_live.rtmp',
            'hx_live.flv',
            'hx_live.is_hot',
            'hx_store.id as store_id',
            "ROUND(
                6378.138 * 2 * ASIN(
                    SQRT(
                        POW(
                            SIN(
                                (
                                    ".$lat."  * PI() / 180 - hx_store.latitude * PI() / 180
                                ) / 2
                            ),
                            2
                        ) + COS(".$lat." * PI() / 180) * COS(hx_store.latitude * PI() / 180) * POW(
                            SIN(
                                (
                                    ".$lon." * PI() / 180 - hx_store.longitude * PI() / 180
                                ) / 2
                            ),
                            2
                        )
                    )
                ) * 1000
            ) /1000 AS distance"
        ];
        $select = implode($select,',');

        $where = ' hx_live.status = 1 ';
        if($distance) {
            $where.= " and ROUND(
            6378.138 * 2 * ASIN(
                SQRT(
                    POW(
                        SIN(
                            (
                                ".$lat."  * PI() / 180 - hx_store.latitude * PI() / 180
                            ) / 2
                        ),
                        2
                    ) + COS(".$lat." * PI() / 180) * COS(hx_store.latitude * PI() / 180) * POW(
                        SIN(
                            (
                                ".$lat." * PI() / 180 - hx_store.longitude * PI() / 180
                            ) / 2
                        ),
                        2
                    )
                )
            ) * 1000
        ) < " . $distance * 1000;
        }

        //点赞
        $xk1 =  DB::table('live')->selectRaw($select)
            ->leftJoin('user','live.user_id','user.id')
            ->leftJoin('picture','user.portrait','picture.id')
            ->leftJoin('store','live.store_id','store.id')
            ->where('live.status',1)
            ->where('live.is_hot',0)
            ->orderBy('live.id','desc');

        //距离
        $xk2 =  DB::table('live')->selectRaw($select)
            ->leftJoin('user','live.user_id','user.id')
            ->leftJoin('picture','user.portrait','picture.id')
            ->leftJoin('store','live.store_id','store.id')
            ->whereRaw($where)
            ->orderBy('distance','asc')
            ->limit('5');

        //热门
        $query =  DB::table('live')->selectRaw($select)
            ->leftJoin('user','live.user_id','user.id')
            ->leftJoin('picture','user.portrait','picture.id')
            ->leftJoin('store','live.store_id','store.id')
            ->where('live.status',1)
            ->where('live.is_hot',1)
            ->orderBy('live.id','desc')
//            ->limit('5')
//            ->union($xk2)
            ->unionAll($xk1)
        ;

        $querySql = $query->toSql();
        $live_list = DB::table(DB::raw("($querySql) as a"))->mergeBindings($query)->orderBy('is_hot','desc')->orderBy('id','desc')
            ->paginate($pageSize, ['*'], 'paginate',$page)->toarray();

        //处理分页数据
        $activity_list = Utilities::dealPage($live_list);
        return $activity_list;
    }

    /**
     * 获取房间信息
     * @param $live_id
     * @return mixed
     * @throws AllValidatorException
     * @throws \Flower\Core\Repository\Exceptions\RepositoryException
     */
    public function getRoomInfo($live_id)
    {
        //主播信息
        $live = $this->liveRepository->pushCriteria(new LiveCriteria($live_id))->first();
        //用户排名
        $list = $this->liveRepository->getLiveList();
        $num = 0;//未直播排名返回0
        for($i=0;$i<count($list);$i++) {
            if($list[$i]['id'] == $live_id) {
                $num = $i+1;
                continue;
            }
        }
        $live['num'] = $num;
        //点赞数
        $like_num = $this->liveLikeRepository->getLiveLikeNum($live_id);
        $live['like_num'] = $like_num;
        //粉丝数
        $attention_num = $this->liveAttentionRepository->getLiveAttentionNum($live->user_id);
        $live['attention_num'] = $attention_num;
        //是否关注
        $attention = $this->liveAttentionRepository->getAttention(FLAuth::id(),$live->user_id);
        if($attention) {
            $live['is_attention'] = 1;
        }else {
            $live['is_attention'] = 0;
        }
        if (!$live) {
            throw new AllValidatorException(['msg' => '直播不存在', 'statusCode' => 400, 'errorCode' => 1404]);
        }
        return $live;
    }

    /**
     * 获取access_token
     * @return mixed
     */
    public function getAccessToken()
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx9c39955dd08a4938&secret=80d1573b4d4ca9272b6d794a689b465f';
        $headerArray =array("Content-type:application/json;","Accept:application/json");
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
        $output = curl_exec($ch);
        curl_close($ch);
        $output = json_decode($output,true);
        return $output;
    }

    /**
     * 获取分享二维码
     * @param $page
     * @param $live_id
     * @return string
     */
    public function getQrcode($page,$live_id)
    {
        //获取access_token
        $access_token = '';

       $res =  DB::table("access_token")->where('id',1)->first();
        if(time()-strtotime($res->created_at) > 1) {
            //超过1小时重新获取accesstoken
            $result = self::getAccessToken();
            $access_token = $result['access_token'];
            DB::table("access_token")->where('id',1)->update(['token'=>$access_token,'created_at'=>date('Y-m-d H:i:s')]);
        }else {
            $access_token = $res->token;
        }

        $data['scene'] = "live_id=$live_id";
        $data['page'] = $page;
        $data  = json_encode($data);
        //获取二维码
        $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='.$access_token;
        $headerArray =array("Content-type:application/json;charset='utf-8'","Accept:application/json");
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        $res = json_decode($output,true);

        if($res) {
            return $res;
        }else {
            $imgDir = 'images/qrcode/';
            $filename= $live_id.time().".jpg";///要生成的图片名字

            file_put_contents("./".$imgDir.$filename,$output);
            $xmlstr = file_get_contents("./".$imgDir.$filename);

            $jpg = $xmlstr;//得到post过来的二进制原始数据
            if(empty($jpg))
            {
                echo 'nostream';
                exit();
            }

            $file = fopen("./".$imgDir.$filename,"w");//打开文件准备写入
            fwrite($file,$jpg);//写入
            fclose($file);//关闭

            $filePath = $_SERVER["HTTP_HOST"].'/'.$imgDir.$filename;

            return $filePath;
        }
    }

    /**
     * 获取直播参数
     * @param $live_id
     * @return mixed
     */
    public function getLiveMessage($live_id)
    {
        $live = $this->liveRepository->getLiveMessage($live_id);
        $user = Db::table('member')->where('id',FLAuth::id())->first();
        $data['liveId'] = $live->id;
        $data['storeId'] = $live->store_id;
        $data['flv'] = $live->flv;
        $data['uerId'] = $live->user_id;
        $data['open_id'] = $user->open_id;
        $data['source'] = 66;

        return $data;
    }

    /**
     * 根据id获取用户昵称
     * @param $member_id
     * @return mixed
     * @throws AllValidatorException
     */
    public function getMemberInfo($member_id)
    {
        $member = $this->memberRepository->getMemberInfo($member_id);
        if (!$member) {
            throw new AllValidatorException(['msg' => '用户不存在', 'statusCode' => 400, 'errorCode' => 1404]);
        }
        return $member;
    }

    /**
     * 用户进入直播间
     * @param $member_id
     * @param $live_id
     * @return mixed
     * @throws AllValidatorException
     */
    public function addLiveMember($member_id,$live_id)
    {
        $live = $this->liveMemberRepository->getLiveMember($member_id,$live_id);
        if(!$live) {
            $liveMember = $this->liveMemberRepository->createLiveMember($member_id,$live_id);
            $this->liveRepository->setIncLive($live_id);
        }else {
            $liveMember = $live;
        }
        return $liveMember;

    }

    /**
     * 退出直播间
     * @param $member_id
     * @param $live_id
     * @return bool
     * @throws AllValidatorException
     */
    public function editLiveMember($member_id,$live_id)
    {
        $live = $this->liveMemberRepository->getLiveMember($member_id,$live_id);
        if($live) {
            //更新数据
            $this->liveRepository->setDecLive($live_id);
            $liveMember = $this->liveMemberRepository->editLiveMember($member_id,$live_id);
        }else {
            $liveMember = $live;
        }

        return $liveMember;
    }


    /**
     * 获取在线用户列表
     * @param $live_id
     * @param $pageSize
     * @return array|mixed
     * @throws \Flower\Core\Repository\Exceptions\RepositoryException
     */
    public function getLiveMemberListPage($live_id,$pageSize)
    {
        $member_list = $this->liveMemberRepository->pushCriteria(new LiveMemberCriteria($live_id))->paginate($pageSize, ['*'], 'paginate');

        //处理分页数据
        $activity_list = Utilities::dealPage($member_list);
        return $activity_list;
    }

    /**
     * 点赞
     * @param $member_id
     * @param $live_id
     * @return mixed
     * @throws AllValidatorException
     */
    public function addLiveLike($member_id,$live_id)
    {
        $liveLike = $this->liveLikeRepository->createLiveLike($member_id,$live_id);
        return $liveLike;
    }

    /**
     * 取消点赞
     * @param $member_id
     * @param $live_id
     * @return mixed
     * @throws AllValidatorException
     */
    public function updateLiveLike($member_id,$live_id)
    {
        $livelike = $this->liveLikeRepository->editLiveLike($member_id,$live_id);
        return $livelike;
    }

    /**
     * 关注
     * @param $member_id
     * @param $user_id
     * @return mixed
     * @throws AllValidatorException
     */
    public function addLiveAttention($member_id,$user_id)
    {
        $liveLike = $this->liveAttentionRepository->createLiveAttention($member_id,$user_id);
        return $liveLike;
    }

    /**
     * 取消关注
     * @param $member_id
     * @param $user_id
     * @return mixed
     * @throws AllValidatorException
     */
    public function updateLiveAttention($member_id,$user_id)
    {
        $livelike = $this->liveAttentionRepository->editLiveAttention($member_id,$user_id);
        return $livelike;
    }
}